package com.pay.demo.tech.statemachine;

import com.pay.demo.enums.PayStatusChangeEventEnum;
import com.pay.demo.enums.PayStatusEnum;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.GenericTypeResolver;
import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.StateMachineConfiguration;
import org.squirrelframework.foundation.fsm.UntypedStateMachine;
import org.springframework.context.ApplicationContextAware;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;

/**
 * @program: demo
 * @description:
 * @author: guoxh
 * @create: 2019-04-04 13:40
 **/
public abstract class AbstractStateMachineEngine<T extends UntypedStateMachine> implements ApplicationContextAware {
    protected UntypedStateMachineBuilder stateMachineBuilder = null;
    private ApplicationContext applicationContext;

    @SuppressWarnings("unchecked")
    public AbstractStateMachineEngine() {
        //识别泛型参数
        Class<T> genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(),
                AbstractStateMachineEngine.class);
        stateMachineBuilder = StateMachineBuilderFactory.create(genericType, ApplicationContext.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //delegate fire
    public void fire(PayStatusEnum initialState, PayStatusChangeEventEnum trigger, PayStateMachineContext context) {
        T stateMachine = stateMachineBuilder.newUntypedStateMachine(
                initialState,
                //暂时开启debug进行日志trace
                StateMachineConfiguration.create().enableDebugMode(true).enableAutoStart(true),
                //注入applicationContext
                applicationContext);
        stateMachine.fire(trigger, context);
    }
}
